﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lucene.Net.Analysis;
using Lucene.Net.Documents;
using Analyzer = Lucene.Net.Analysis.Analyzer;
using StandardAnalyzer = Lucene.Net.Analysis.Standard.StandardAnalyzer;
using Document = Lucene.Net.Documents.Document;
using Field = Lucene.Net.Documents.Field;
using IndexWriter = Lucene.Net.Index.IndexWriter;
using ParseException = Lucene.Net.QueryParsers.ParseException;
using QueryParser = Lucene.Net.QueryParsers.QueryParser;
using Directory = Lucene.Net.Store.Directory;
using RAMDirectory = Lucene.Net.Store.RAMDirectory;
using Version = Lucene.Net.Util.Version;
using IndexSearcher = Lucene.Net.Search.IndexSearcher;
using Query = Lucene.Net.Search.Query;
using ScoreDoc = Lucene.Net.Search.ScoreDoc;
using Store = Lucene.Net.Store;
using Could.Service;
using IO = System.IO;
using System.Diagnostics;
using Lucene.Net.Index;
using MySql.Data.MySqlClient;
using System.Collections;

namespace CatSentenceAnalyzer
{
    public class TMSIndexClass :CatIndexClass
    {
        public TMSIndexClass(){
            m_EngineSql = new TmsMysql();
        }
        public override void CommandExe()
        {
            m_EngineSql.m_npc = m_npc;
            base.CommandExe();
        }
        public override void CreateIndex()
        {
            using( MySqlDataReader reader =  m_EngineSql.SelectFrom())
            {
                Store.Directory directory = IndexDirectory;
                Analyzer analyzer =null;
                IndexWriter writer = null;
                Single boost = 0f;
                try
                {
                    analyzer = GetCatAnalyzer(CLangSegment.TMSALLINDEXTYPE);
                    writer = GetCatWriter(directory, analyzer); 
                    while (reader.Read())
                    {
                        Document doc = new Document();
                        boost = Convert.ToInt32(reader.GetValue(reader.GetOrdinal(SqlDB.USAGECOUT)).ToString());
                        doc.Add(new Field(SqlDB.IDFIELD, reader.GetValue(reader.GetOrdinal(SqlDB.IDFIELD)).ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                        doc.Add(new Field(SqlDB.USAGECOUT, boost.ToString(), Field.Store.YES, Field.Index.NO));
                        doc.Add(new Field(SqlDB.TEXTFIELD, reader.GetValue(reader.GetOrdinal(m_npc.transdata.textTmsField)).ToString(), Field.Store.YES, Field.Index.NO));
                        doc.Add(new Field(SqlDB.INDEXFIELD, reader.GetValue(reader.GetOrdinal(m_npc.transdata.indexTmsField)).ToString(), Field.Store.YES, Field.Index.ANALYZED));
                        doc.SetBoost(boost);
                        writer.AddDocument(doc);
                    }
                }
                catch (System.Exception) { }
                finally
                {
                    writer.Optimize();
                    writer.Close();
                    directory.Close();
                }
            }
        }
        public override void DeleteIndex()
        {
            if (m_EngineSql.DeleteFromID())
            {
                int i;
                Store.Directory directory = IndexDirectory;
                IndexReader reader = IndexReader.Open(directory, false);
                Term term = new Term(SqlDB.IDFIELD, m_npc.transdata.TmsID.ToString());
                i = reader.DeleteDocuments(term);
                reader.Close();
                directory.Close();
            }
        }
        public override void UpdateIndex()
        {
            Tms tms = m_arrResult[0] as Tms;
            if (m_npc.transdata.TSentence != tms.tText)//译文不同， 修改
            {
                m_npc.transdata.TmsID = Convert.ToInt32( tms.ID );
                if (m_EngineSql.UpdateFromID())
                {
                    Store.Directory directory = IndexDirectory;
                    Analyzer analyzer = GetCatAnalyzer(CLangSegment.TMSALLINDEXTYPE);
                    IndexWriter iwriter = GetCatWriter(directory, analyzer);
                    Document doc = new Document();
                    doc.Add(new Field(SqlDB.IDFIELD, tms.ID, Field.Store.YES, Field.Index.NOT_ANALYZED));//NO
                    doc.Add(new Field(SqlDB.TEXTFIELD, m_npc.transdata.TSentence, Field.Store.YES, Field.Index.NO));
                    doc.Add(new Field(SqlDB.INDEXFIELD, m_npc.transdata.OSentence, Field.Store.YES, Field.Index.ANALYZED));
                    iwriter.UpdateDocument(new Term(SqlDB.IDFIELD, tms.ID), doc);
                    iwriter.Close();
                    directory.Close();
                }
                else
                { //增加使用次数
                    ((TmsMysql)(m_EngineSql)).UpdateFrom_UsageCount(tms.ID);
                }
            }
        }
        public override void SearchIndex()
        {
            string key = GetTokens(m_npc.transdata.OSentence, CLangSegment.MININDEXTYPE);
            if (SearchIndex(key))
            {
                UpdateIndex();
            }
            else
            {
                AddNewIndex();
            }
        }
        
        public override void FuzzyIndex()
        {
            FuzzyIndex(CLangSegment.MAXINDEXTYPE - CLangSegment.MININDEXTYPE);
        }
        public override void FuzzyIndex(int level)
        {
            int i; Hashtable ht = new Hashtable();
            int k  = CLangSegment.MININDEXTYPE + level;
            if ( k > CLangSegment.MAXINDEXTYPE){
                k = CLangSegment.MAXINDEXTYPE;
            }
            m_npc.transdata.TmsSearchLevel = 0;
            m_npc.transdata.ArrList = null;
            for (i = CLangSegment.MININDEXTYPE; i <= k; i++)
            {
                string key = GetTokens(m_npc.transdata.OSentence, i);
                if (key == "") return;
                if (!ht.ContainsKey(key))
                {
                    ht.Add(key, key);
                    if (SearchIndex(key))
                    {
                        m_npc.transdata.TmsSearchLevel = i;
                        break;
                    }
                }
            }
            m_npc.transdata.ArrList = m_arrResult; //结果集
        }

        public override Boolean AddNewIndex()
        {
            int newid = m_EngineSql.InsertInto(); 
            if (newid > 0)
            {
                Store.Directory directory = IndexDirectory;
                Analyzer analyzer = GetCatAnalyzer(CLangSegment.TMSALLINDEXTYPE);
                IndexWriter writer = GetCatAppendWriter(directory, analyzer); 
                Document doc = new Document();
                doc.Add(new Field(SqlDB.IDFIELD, newid.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                doc.Add(new Field(SqlDB.USAGECOUT, "0", Field.Store.YES, Field.Index.NO));
                doc.Add(new Field(SqlDB.TEXTFIELD, m_npc.transdata.TSentence, Field.Store.YES, Field.Index.NO));
                doc.Add(new Field(SqlDB.INDEXFIELD, m_npc.transdata.OSentence, Field.Store.YES, Field.Index.ANALYZED));
                writer.AddDocument(doc);
                //writer.Commit();
                writer.Close();
                directory.Close();
            }
            return newid>0;
        }


        public override Boolean SearchIndex(string key)
        {
            Store.Directory directory = IndexDirectory;
            IndexSearcher isearcher = new IndexSearcher(directory, true); // read-only=true
            WhitespaceAnalyzer analyzer = new WhitespaceAnalyzer();
            QueryParser parser = new QueryParser(Version.LUCENE_29, SqlDB.INDEXFIELD, analyzer);
            Query query = parser.Parse(key);
            ScoreDoc[] hits = isearcher.Search(query, null, 100).scoreDocs;

            m_arrResult = new ArrayList();
            for (int i = 0; i < hits.Length; i++)
            {
                Document hitDoc = isearcher.Doc(hits[i].doc);
                Tms tms = new Tms();
                tms.ID = hitDoc.Get(SqlDB.IDFIELD);
                tms.oText = hitDoc.Get(SqlDB.INDEXFIELD);
                tms.tText = hitDoc.Get(SqlDB.TEXTFIELD);
                m_arrResult.Add(tms);
            }
            isearcher.Close();
            directory.Close();
            return m_arrResult.Count > 0;
        }

        public override void ReadDocs(int min, int max)
        {
            Store.Directory directory = IndexDirectory;
            IndexReader reader = IndexReader.Open(directory, true);
            for (int i = min; i < max && i < reader.MaxDoc(); i++ )
            {
                if (!reader.IsDeleted(i))
                {
                    Document doc = reader.Document(i);
                }
            }
        }

        public override void MaketransData()
        {
            TransData td = m_npc.transdata;
            td.TmsTitle = ("匹配结果: 获得|1|条结果, 用时(|2|秒)");
            td.TmsTitle = td.TmsTitle.Replace("|1|", td.ArrList.Count.ToString());
            td.TmsTitle = td.TmsTitle.Replace("|2|", ((Convert.ToSingle(td.ElapsedTime)) / 1000).ToString());
            //string tmp = td.TmsResult = "";
            //string sample = "<li><font size='13' color='#|3|'>|1|</font>\n<font size='13' color='#3399ff'>|2|</font></li>\n";
            //for (int i = 0; i < m_arrResult.Count; i++)
            //{
            //    Tms tms = m_arrResult[i] as Tms;
            //    tmp += sample.Replace("|1|", tms.oText);
            //    tmp = tmp.Replace("|2|", tms.tText);
            //    tmp = tmp.Replace("|3|", m_Color[td.TmsSearchLevel - CLangSegment.MININDEXTYPE].ToString());
            //}
            //td.TmsResult = tmp;
        }
    }

    public class PrivateTMSIndexClass : TMSIndexClass
    {
        public PrivateTMSIndexClass()
        {
            MainIndex = false;
            m_EngineSql = new PrivateTmsMysql();
        }
        public override void CommandExe()
        {
            m_Indexpath = m_npc.PrivateIndexTMSPath;
            base.CommandExe();
        }
    }
    public class MainTMSIndexClass : TMSIndexClass
    {
        public MainTMSIndexClass()
        {
            MainIndex = true;
            m_EngineSql = new MainTmsMysql();
        }
        public override void CommandExe()
        {
            m_Indexpath = m_npc.MainIndexTMSPath;
            base.CommandExe();
        }

    }
}
